#ifndef RDA5807M_H
#define RDA5807M_H

#include "i2c.h"
#include <string.h>

#define RDA5807M_ADDRESS 0x11
#define RDA5807M_FIRST_REGISTER_WRITE 0x02
#define RDA5807M_FIRST_REGISTER_READ 0x0A
#define RDA5807M_LAST_REGISTER 0x3A

//Register addresses
#define RDA5807M_REG_CHIPID 0x00
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_GPIO 0x04
#define RDA5807M_REG_VOLUME 0x05
#define RDA5807M_REG_I2S 0x06
#define RDA5807M_REG_BLEND 0x07
#define RDA5807M_REG_FREQ 0x08
#define RDA5807M_REG_STATUS 0x0A
#define RDA5807M_REG_RSSI 0x0B
#define RDA5807M_REG_RDSA 0x0C
#define RDA5807M_REG_RDSB 0x0D
#define RDA5807M_REG_RDSC 0x0E
#define RDA5807M_REG_RDSD 0x0F
#define RDA5807M_REG_SEEK 0x20

//Status bits (from the chip)
#define RDA5807M_STATUS_RDSR 0x8000
#define RDA5807M_STATUS_STC 0x4000
#define RDA5807M_STATUS_SF 0x2000
#define RDA5807M_STATUS_RDSS 0x1000
#define RDA5807M_STATUS_BLKE 0x0800
#define RDA5807M_STATUS_ST 0x0400

//Flag bits (to the chip)
#define RDA5807M_FLG_DHIZ 0x8000
#define RDA5807M_FLG_DMUTE 0x4000
#define RDA5807M_FLG_MONO 0x2000
#define RDA5807M_FLG_BASS 0x1000
#define RDA5807M_FLG_RCLKNOCAL 0x0800
#define RDA5807M_FLG_RCLKDIRECT 0x0400
#define RDA5807M_FLG_SEEKUP 0x0200
#define RDA5807M_FLG_SEEKDOWN 0x0000
#define RDA5807M_FLG_SEEK 0x0100
#define RDA5807M_FLG_SKMODE 0x0080
#define RDA5807M_FLG_RDS 0x0008
#define RDA5807M_FLG_NEW 0x0004
#define RDA5807M_FLG_RESET 0x0002
#define RDA5807M_FLG_ENABLE 0x0001
#define RDA5807M_FLG_DIRECT 0x0020
#define RDA5807M_FLG_TUNE 0x0010
#define RDA5807M_FLG_DE 0x0800
#define RDA5807M_FLG_SOFTMUTE 0x0200
#define RDA5807M_FLG_AFCD 0x0100
#define RDA5807P_FLG_INTMODE 0x8000
#define RDA5807M_FLG_EASTBAND65M 0x0200
#define RDA5807M_FLG_SOFTBLEND 0x0002
#define RDA5807M_FLG_FREQMODE 0x0001
#define RDA5807M_FLG_FMTRUE 0x0100
#define RDA5807M_FLG_FMREADY 0x0080
#define RDA5807M_FLG_BLOCKE 0x0010
#define RDA5807M_CHIPID 0x58
#define RDA5807M_CLKMODE_MASK 0x0070
#define RDA5807M_CLKMODE_32K (0x0 << 4)
#define RDA5807M_CLKMODE_12M (0x1 << 4)
#define RDA5807M_CLKMODE_13M (0x2 << 4)
#define RDA5807M_CLKMODE_19M (0x3 << 4)
#define RDA5807M_CLKMODE_24M (0x5 << 4)
#define RDA5807M_CLKMODE_26M (0x6 << 4)
#define RDA5807M_CLKMODE_38M (0x7 << 4)
#define RDA5807M_CHAN_MASK 0xFFC0
#define RDA5807M_CHAN_SHIFT 6
#define RDA5807M_BAND_MASK 0x000C
#define RDA5807M_BAND_SHIFT 2
#define RDA5807M_BAND_WEST (0x0 << 2)
#define RDA5807M_BAND_JAPAN (0x1 << 2)
#define RDA5807M_BAND_WORLD (0x2 << 2)
#define RDA5807M_BAND_EAST (0x3 << 2)
#define RDA5807M_SPACE_MASK 0x0003
#define RDA5807M_SPACE_100K 0x0
#define RDA5807M_SPACE_200K 0x1
#define RDA5807M_SPACE_50K 0x2
#define RDA5807M_SPACE_25K 0x3
#define RDA5807M_SEEKTH_MASK 0x7F00
#define RDA5807M_SEEKTH_SHIFT 8
#define RDA5807M_VOLUME_MASK 0x000F
#define RDA5807M_VOLUME_SHIFT 0
#define RDA5807M_OPENMODE_MASK 0x6000
#define RDA5807M_OPENMODE_WRITE (0x3 << 13)
#define RDA5807M_SOFTBLENDTH_MASK 0x7C00
#define RDA5807M_SOFTBLENDTH_SHIFT 10
#define RDA5807M_SEEKTHOLD_MASK 0x00FC
#define RDA5807M_SEEKTHOLD_SHIFT 2
#define RDA5807M_SEEKMODE_MASK 0x7000
#define RDA5807M_SEEKMODE_OLD (0x1 << 12)
#define RDA5807M_READCHAN_MASK 0x03FF
#define RDA5807M_RSSI_MASK 0xFE00
#define RDA5807M_RSSI_SHIFT 10
#define RDA5807M_BLERA_MASK 0x000C
#define RDA5807M_BLERA_0 (0x0 << 2)
#define RDA5807M_BLERA_12 (0x1 << 2)
#define RDA5807M_BLERA_35 (0x2 << 2)
#define RDA5807M_BLERA_U (RDA5807M_BLERA_12 | RDA5807M_BLERA_35)
#define RDA5807M_BLERB_MASK 0x0003
#define RDA5807M_BLERB_0 0x0
#define RDA5807M_BLERB_12 0x1
#define RDA5807M_BLERB_35 0x2
#define RDA5807M_BLERB_U (RDA5807M_BLERB_12 | RDA5807M_BLERB_35)
#define RDA5807M_RDSA 0x0C
#define RDA5807M_RDSB 0x0D
#define RDA5807M_RDSC 0x0E
#define RDA5807M_RDSD 0x0F

typedef enum 
{
	RDA5807M_INIT_OK = 0,
	RDA5807M_WAIT_INIT
}RDA5807M_States_Typedef;

typedef enum 
{
	RDA5807M_ON = 0,
	RDA5807M_OFF
}RDA5807M_PowerMode_Typedef;

typedef enum 
{
	RDA5807M_RSSI_WAIT = 0,
	RDA5807M_RSSI_UPDATE
}RDA5807M_Update_States_Typedef;

typedef struct
{
	uint8_t RSSI;
	float Frequency;
	uint8_t RDS_Text[9];
}RDA5807M_Data_Typedef;

void RDA5807M_Init(void);
void RDA5807M_SetFrequency(float Freq);
void RDA5807M_SeekUp(void);
void RDA5807M_SeekDown(void);
uint8_t RDA5807M_GetRSSI(void);
void RDA5807M_GetRDS(RDA5807M_Data_Typedef *Struct);
float RDA5807M_GetFrequency(void);

#endif
